package com.htthorizon.model.service;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

import com.htthorizon.common.core.constant.Constants;
import com.htthorizon.common.core.utils.DateUtils;
import com.htthorizon.common.core.utils.StringUtils;
import com.htthorizon.common.security.utils.SecurityUtils;
import com.htthorizon.model.domain.ModelInfo;
import com.htthorizon.model.domain.ModelSourceParam;
import com.htthorizon.model.mapper.ModelInfoMapper;
import com.htthorizon.model.mapper.ModelSourceParamMapper;
import com.htthorizon.model.request.ModelSourceParamReq;
import com.htthorizon.model.request.ModelSourceReq;
import com.htthorizon.util.ServiceMarketHTTPUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.htthorizon.model.mapper.ModelSourceMapper;
import com.htthorizon.model.domain.ModelSource;
import org.springframework.util.CollectionUtils;

/**
 * 数据源配置Service业务层处理
 *
 * @author mark
 * @date 2023-11-20
 */
@Service
@Slf4j
public class ModelSourceServiceImpl implements IModelSourceService
{
    @Autowired
    private ModelSourceMapper modelSourceMapper;

    @Autowired
    private ModelSourceParamMapper modelSourceParamMapper;

    @Autowired
    private ServiceMarketHTTPUtil serviceMarketHTTPUtil;

    @Autowired
    private ModelInfoMapper modelInfoMapper;

    /**
     * 查询数据源配置
     *
     * @param id 数据源配置主键
     * @return 数据源配置
     */
    @Override
    public ModelSource selectModelSourceById(Long id)
    {
        Optional<ModelSource> modelSourceOptional = Optional.ofNullable(modelSourceMapper.selectModelSourceById(id));
        if(modelSourceOptional.isPresent()){
            ModelSource modelSource = modelSourceOptional.get();
            ModelSourceParam param = new ModelSourceParam();
            param.setSourceId(modelSource.getId());
            List<ModelSourceParam> params = modelSourceParamMapper.selectModelSourceParamList(param);
            modelSource.setSourceParams(params);
            return modelSource;
        }
        return null;
    }

    /**
     * 查询数据源配置列表
     *
     * @param modelSource 数据源配置
     * @return 数据源配置
     */
    @Override
    public List<ModelSource> selectModelSourceList(ModelSource modelSource)
    {
        return modelSourceMapper.selectModelSourceList(modelSource);
    }

    @Override
    public List<ModelSource> selectModelSourceList2(ModelSource modelSource,Integer pageNum ,Integer pageSize)
    {

        List<ModelSource> modelSources = modelSourceMapper.selectModelSourceList(modelSource);
        List<ModelInfo> list = modelInfoMapper.list();
        List<Long> sourceIds = modelSources.stream().map(ModelSource::getId).collect(Collectors.toList());
        Set<Long> infoIds = list.stream().map(ModelInfo::getSourceId).collect(Collectors.toSet());

        sourceIds.removeAll(infoIds);
        if (sourceIds.size()==0){
            return new ArrayList<>();
        }
        List<ModelSource> modelSources1 = modelSourceMapper.selectModelSourceByIds(sourceIds);
        return this.page(pageNum,pageSize,modelSources1);


    }

    @Override
    public boolean checkSourceName(ModelSourceReq modelSource) {
        return modelSourceMapper.countModelSourceByModelName(modelSource.getSourceTable())==0;
    }

    private List<ModelSource> page(Integer pageNum,Integer pageSize,List<ModelSource> list){
        if (list == null) {
            return null;
        }
        if (list.size() == 0) {
            return null;
        }

        Integer count = list.size(); // 记录总数
        Integer pageCount = 0; // 页数
        if (count % pageSize == 0) {
            pageCount = count / pageSize;
        } else {
            pageCount = count / pageSize + 1;
        }

        int fromIndex = 0; // 开始索引
        int toIndex = 0; // 结束索引

        if (pageNum != pageCount) {
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = fromIndex + pageSize;
        } else {
            fromIndex = (pageNum - 1) * pageSize;
            toIndex = count;
        }

        List<ModelSource> pageList = list.subList(fromIndex, toIndex);

        return pageList;
    }

    /**
     * 新增数据源配置
     *
     * @param modelSourceReq 数据源配置
     * @return 结果
     */
    @Override
    public int insertModelSource(ModelSourceReq modelSourceReq)
    {
        ModelSource modelSource = new ModelSource();
        BeanUtils.copyProperties(modelSourceReq, modelSource);
        modelSource.setCreateTime(DateUtils.getNowDate());
        modelSource.setCreateBy(SecurityUtils.getUsername());
        modelSource.setStatus(Constants.DELETE_STATUS_NO);
        int mid = modelSourceMapper.insertModelSource(modelSource);
        ModelSourceParam modelSourceParam = null;
        if(!CollectionUtils.isEmpty(modelSourceReq.getSourceParams())){
            for (ModelSourceParamReq paramReq : modelSourceReq.getSourceParams()){
                modelSourceParam = new ModelSourceParam();
                BeanUtils.copyProperties(paramReq, modelSourceParam);
                modelSourceParam.setCreateTime(DateUtils.getNowDate());
                modelSourceParam.setCreateBy(SecurityUtils.getUsername());
                modelSourceParam.setStatus(Constants.DELETE_STATUS_NO);
                modelSourceParam.setSourceId(modelSource.getId());
                int isSuccess = modelSourceParamMapper.insertModelSourceParam(modelSourceParam);
            }
        }
        return mid;
    }

    /**
     * 修改数据源配置
     *
     * @param modelSourceReq 数据源配置
     * @return 结果
     */
    @Override
    public int updateModelSource(ModelSourceReq modelSourceReq)
    {
        ModelSource modelSource = new ModelSource();
        BeanUtils.copyProperties(modelSourceReq, modelSource);
        modelSource.setUpdateTime(DateUtils.getNowDate());
        modelSource.setUpdateBy(SecurityUtils.getUsername());
        int isSuccess = modelSourceMapper.updateModelSource(modelSource);
        if(!CollectionUtils.isEmpty(modelSourceReq.getSourceParams())){
            ModelSourceParam modelSourceParam = null;
            for (ModelSourceParamReq paramReq : modelSourceReq.getSourceParams()){
                modelSourceParam = new ModelSourceParam();
                BeanUtils.copyProperties(paramReq, modelSourceParam);
                if(modelSourceParam.getId() != null && modelSourceParam.getId() > 0L) {
                    modelSourceParam.setUpdateTime(DateUtils.getNowDate());
                    modelSourceParam.setUpdateBy(SecurityUtils.getUsername());
                    modelSourceParamMapper.updateModelSourceParam(modelSourceParam);
                }else {
                    modelSourceParam.setCreateTime(DateUtils.getNowDate());
                    modelSourceParam.setCreateBy(SecurityUtils.getUsername());
                    modelSourceParam.setStatus(Constants.DELETE_STATUS_NO);
                    modelSourceParam.setSourceId(modelSource.getId());
                    modelSourceParamMapper.insertModelSourceParam(modelSourceParam);
                }
            }
        }
        return isSuccess;
    }

    /**
     * 批量删除数据源配置
     *
     * @param ids 需要删除的数据源配置主键
     * @return 结果
     */
    @Override
    public int deleteModelSourceByIds(Long[] ids)
    {
        int success = modelSourceMapper.deleteModelSourceByIds(ids);
        if(ids!=null && ids.length>0){
            for (Long sourceId:ids){
                modelSourceParamMapper.deleteModelSourceParamBySourceId(sourceId);
            }
        }
        return success;
    }

    /**
     * 删除数据源配置信息
     *
     * @param id 数据源配置主键
     * @return 结果
     */
    @Override
    public int deleteModelSourceById(Long id)
    {
        int result = modelSourceMapper.deleteModelSourceById(id);
        modelSourceParamMapper.deleteModelSourceParamBySourceId(id);
        return result;
    }
    /**
     * 推荐使用SDK方式
     * */
    @Override
    @Deprecated
    public String testConnection(String host,String appKey,String appSecurity,String requestMethod, String path, String params) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        if ("GET".equals(requestMethod)){
           return serviceMarketHTTPUtil.getMethod(host,appKey,appSecurity, path, params);
        }
        return null;
    }

}
